package com.superbit.web.utils;



import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Random;

import javax.imageio.ImageIO;

/** @author  WangZhenwei 
 *  @date 创建时间：2018年1月5日 下午5:35:35  
 *  @descrip 实现图片验证码的工具类
 *  
 */
public class PictureCheckCode {
	
	//图片的宽度。  
    private static int width = 120;  
    //图片的高度。  
    private static int height = 50;  
    
    private static int stringCodeCount = 4;
    //验证码干扰线数  
    private static int lineCount = 150;  
    //验证码  
    private static String code = null;  
    //验证码图片Buffer  
    private static BufferedImage buffImg = null;  
	
    //验证码的所有字符数组
	private static char[] codeSequence = 
			"0123456789ABCDEFGHIJKLMN0PQRSTUVWXYZabcdefghijkmnpqrstuvwxyz".toCharArray();
	
	
	/**
	 * @function 默认构造器，设置默认参数,默认为绘制数学计算验证码
	 */
	public PictureCheckCode() {
	}
	
	/**
	 * @function 绘制验证码
	 */
	public void createCode(){
		int fontHeight = 0;
		
		fontHeight = height - 2;//字体的高度 
        Graphics2D g = createGraphics2D(fontHeight);
        
        drwaLine(g);
        createStringCode(g);        
	}
	
	/**
	 * @function 创建画板
	 */
	private static Graphics2D createGraphics2D(int fontHeight){
		buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
        Graphics2D g = buffImg.createGraphics(); 
        //将图像填充为白色  
        g.setColor(Color.white);  
        g.fillRect(0, 0, width, height);
        //创建字体,可以修改为其它的  
        Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);  
        //Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);  
        g.setFont(font); 
        return g;
	}
	
	/**
	 * @function 绘制干扰线方法，为内部方法，传入画笔绘制
	 * @param g
	 */
	private static void drwaLine(Graphics2D g){
		Random random = new Random();
		int red,green,blue;
		for (int i = 0; i < lineCount; i++) {  
            //设置随机开始和结束坐标  
            int xs = random.nextInt(width);				//x坐标开始  
            int ys = random.nextInt(height);			//y坐标开始  
            int xe = xs + random.nextInt(width / 8);	//x坐标结束  
            int ye = ys + random.nextInt(height / 8);	//y坐标结束  
  
            //产生随机的颜色值，让输出的每个干扰线的颜色值都将不同。  
            red = random.nextInt(255);  
            green = random.nextInt(255);  
            blue = random.nextInt(255);  
            g.setColor(new Color(red, green, blue));  
            g.drawLine(xs, ys, xe, ye);  
        }  
	}
	
	
	/**
	 * @function 生成字符串验证码
	 */
	private static Object createStringCode(Graphics2D g){
		//randomCode记录随机产生的验证码  
		int x = 0, codeY = 0;  
		  
        x = width / (stringCodeCount + 2);//每个字符的宽度(左右各空出一个字符)  
         
        codeY = height - 4;  
		Random random = new Random();
		StringBuffer randomCode = new StringBuffer(); 
		//随机产生codeCount个字符的验证码。  
        for (int i = 0; i < stringCodeCount; i++) {  
            String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);  
            //产生随机的颜色值，让输出的每个字符的颜色值都将不同。  
//        	int red,green,blue;
//          red = random.nextInt(255);  
//         	green = random.nextInt(255);  
//         	blue = random.nextInt(255);  
            g.setColor(Color.blue);  
//          g.setColor(new Color(red, green, blue));  
            g.drawString(strRand, (i + 1) * x, codeY);  
            //将产生的四个随机数组合在一起。  
            randomCode.append(strRand);  
        }  
        //将四位数字的验证码保存到Session中。  
        code = randomCode.toString();  
    
		return null;
	}
	
	/**
	 * @function 将验证码图片写入缓存
	 * @param path
	 * @throws IOException
	 */
	public void write(String path) throws IOException {  
        OutputStream sos = new FileOutputStream(path);  
        this.write(sos);  
    }  
	
	/**
	 * @function 将验证码图片写入缓存
	 * @param sos
	 * @throws IOException
	 */
	public void write(OutputStream sos) throws IOException {  
        ImageIO.write(buffImg, "png", sos);  
        sos.close();  
    }  
	
	public BufferedImage getBuffImg() {  
        return buffImg;  
    }  
	
	public String getCode() {  
        return code;  
    }  
	
	/**
	 * @function 测试方法 
     * @param args 
     */  
    public static void main(String[] args) {  
    	PictureCheckCode vCode = new PictureCheckCode(); 
    	vCode.createCode();
    	vCode.getCode();
    	try {  
            String path="F:/c2c/"+new Date().getTime()+".png";  
            System.out.println(vCode.getCode()+" >"+path);  
            vCode.write(path);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
//    	//7.将随机数存在session中
//	    request.getSession().setAttribute("checkcode", random);
//	    //8.设置响应头通知浏览器以图片的形式打开
//	    response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
//	    //9.设置响应头控制浏览器不要缓存
//	    response.setDateHeader("expries", -1);
//	    response.setHeader("Cache-Control", "no-cache");
//	    response.setHeader("Pragma", "no-cache");
//	    //10.将图片写给浏览器
//	    ImageIO.write(bi, "jpg", response.getOutputStream());
    	
    }  
    
}  
	